package com.robert.BCH;

import java.util.Arrays;

public class demo {
    public static void main(String[] args) throws Exception {
        //预计算一些公共参数，其中6是有限域F_{2^m}中的m
        //m取值范围是3-10
        parameters p = new parameters(6);
        //parameters p = new parameters(new polynomial("10011"),4);
        preCompute pc = new preCompute();
        pc.precomputeAll(p);
        //下面输出的是预计算后的参数
        System.out.println("--------alpha value---------");
        System.out.println(Arrays.deepToString(pc.getAlpha().getValue()));
        System.out.println("--------alpha index---------");
        System.out.println(Arrays.toString(pc.getAlpha().getIndexes()));
        System.out.println("--------cyclotomic set---------");
        System.out.println(pc.getCyclotomic().getCycSet());
        System.out.println("--------cyclotomic auxiliary---------");
        System.out.println(Arrays.toString(pc.getCyclotomic().getAuxiliary()));
        System.out.println("--------message bits---------");
        System.out.println(Arrays.toString(pc.getMsgBits()));
        System.out.println("--------dist of generator poly---------");
        System.out.println(Arrays.toString(pc.getDistGen()));
        System.out.println("--------generator poly---------");
        for(polynomial poly:pc.getGenPoly()){
            System.out.println(Arrays.toString(poly.getNums()));
        }
        bchEncode be = new bchEncode();
        bchDecode bd = new bchDecode();
        //由于生成多项式/码距/明文比特数是一一对应的
        //即比如第一个位置的生成多项式就对应第一个位置的码距就对应第一个位置的明文比特数
        //BCH编码的[n,k,d]分别对应这n=p.getN(), k为明文比特数，d为码距
        //码距为d则其纠错能力为(d-1)/2
        //iPoly是选择第i个生成多项式/码距/明文比特数
        int iPoly = 0;
        //解码500次
        int change = 0;//change统计codeword发生了变化的次数
        for(int i=0;i<500;i++){
            //每次迭代都会修改生成多项式/码距/明文比特数
            iPoly = (iPoly+1)%pc.getDistGen().length;
            //随机产生消息
            polynomial msg = be.genRandomMsg(pc,iPoly);
            //消息如果需要int[]，则调用msg.getNums()
            //编码后结果
            int[] code = be.encode(msg,p,pc,iPoly);
            //扰动码字
            code = bd.disturbCodeword(code,p,pc,iPoly);
            //比较扰动后码字与原来的码字是否相同
            boolean c = bd.isCorrect(be.encode(msg,p,pc,iPoly),code);
            //比较扰动后码字与原来的码字是否相同，如果不同则加1
            if(!c) change++;
            //解码
            int[] msg2 = bd.decode(code,iPoly,p,pc);
            //验证解码是否正确
            boolean correct = bd.isCorrect(msg.getNums(),msg2);
            //如果不正确则输出err
            if(!correct) System.out.println("err!");
        }
        //扰动次数可能不一定是500，因为产生扰动的时候
        //比如扰动两次，选择了codeword的同一个位置，则该位置如果原本是0，则扰动一次变成1，又被选择同一个位置就又变回了0
        System.out.println("码字产生了扰动的次数："+change);
        System.out.println("correct!");
    }
}
